package com.renrenyou.duanshipin.net;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.$Gson$Types;
import com.renrenyou.duanshipin.R;
import com.renrenyou.duanshipin.util.AESUtil;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import javax.net.ssl.SSLHandshakeException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * 请求回调
 *
 * @author hulei
 */
public abstract class MyOkhttpCallback<T> implements Callback {

    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private final Type mType;
    private final String TAG = "MyOkhttpCallback";

    public MyOkhttpCallback() {
        mType = getSuperclassTypeParameter(getClass());
    }

    @Override
    public void onFailure(Call call, IOException e) {
        if (call.isCanceled()) {
            return;
        }
        if (e instanceof SocketTimeoutException) {
            dealWithFailed(-1, R.string.connected_timeout);
        } else if (e instanceof UnknownHostException) {
            dealWithFailed(-3, R.string.connected_failed);
        } else if (e instanceof SSLHandshakeException) {
            dealWithFailed(-4, R.string.str_no_certificate);
        } else {
            e.printStackTrace();
            dealWithFailed(-2, R.string.connected_failed);
        }
    }

    @Override
    public void onResponse(Call call, Response response) {
        if (call.isCanceled()) {
            return;
        }
        if (response.isSuccessful()) {
            ResponseBody body = response.body();
            if (body != null) {
                if (mType == null) {
                    dealWithSuccess(null);
                } else {
                    try {
                        String bodystring = body.string();
                        Log.d(TAG, "返回数据:" + bodystring);
                        if (!AESUtil.isJson(bodystring)) {
                            bodystring = AESUtil.decodeString(bodystring);
                        }
                        T t = new Gson().fromJson(bodystring, mType);
                        dealWithSuccess(t);
                    } catch (JsonSyntaxException | IOException e) {
                        e.printStackTrace();
                        dealWithFailed(response.code(), R.string.parsing_error);
                    }
                }
            } else {
                dealWithFailed(response.code(), R.string.parsing_error);
            }
        } else {
            dealWithFailed(response.code(), R.string.connected_failed);
        }
    }

    private Type getSuperclassTypeParameter(Class<?> subclass) {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class) {
            return null;
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
    }

    private void dealWithFailed(int errorCode, int errorMsg) {
        mHandler.post(() -> onFailed(errorCode, errorMsg));
    }

    private void dealWithSuccess(T t) {
        mHandler.post(() -> onSuccess(t));
    }

    abstract public void onFailed(int errorCode, int errorMsg);

    abstract public void onSuccess(T t);
}
